#ifndef DSPSIMULATOR_DELAYINSTRUCTION_H
#define DSPSIMULATOR_DELAYINSTRUCTION_H


#include <list>
#include <utility>
#include <vector>
#include <bitset>
#include <memory>
#include <simulator/type/type.h>
#include <simulator/instruction/instruction.h>

/**
* 存在延迟delaySlot的指令
*/
class DelayInst {
private:
    u64 m_baseCycle;                            // 延时指令加入延时队列的周期数
    std::list<u64> m_allCycle;                  // 有些延时指令会在多个周期执行,需要存储其执行的多个周期
    std::shared_ptr<Instruction> m_instruction; // 指向延时指令的指针
public:
    /**
     * 构建一个延时指令对象
     * @Param baseCycle 延时指令进入延时队列的周期
     * @param allCycle 延时指令执行的周期数
     * @param instruction 指向延时指令的指针
     */
    DelayInst(u64 baseCycle, const std::list<u64> &allCycle, std::shared_ptr<Instruction> instruction) :
            m_baseCycle(baseCycle), m_allCycle(allCycle), m_instruction(instruction) {};

    virtual ~DelayInst() = default;

    DelayInst(const DelayInst &delayInst) {
        m_allCycle = delayInst.m_allCycle;
        m_baseCycle = delayInst.m_baseCycle;
        m_instruction = delayInst.m_instruction;
    }

    u64 getBaseCycle() const { return m_baseCycle; }

    u64 getTopCycle() const { return m_allCycle.front(); }

    bool isEmptyCycle() const { return m_allCycle.empty(); }

    void popTopCycle() { m_allCycle.pop_front(); }

    std::shared_ptr<Instruction> getInstruction() { return m_instruction; }

    /**
     * 重载>运算符，用于构建最小堆
     * @param instruction
     * @return
     */
    bool operator>(const DelayInst &instruction) {
        return this->m_allCycle.front() > instruction.m_allCycle.front();
    }
};

#endif //DSPSIMULATOR_DELAYINSTRUCTION_H
